﻿using AutoMapper;
using DongFangGuoKai.WMS.ApiService.ElectronicTags;
using DongFangGuoKai.WMS.IApiService;
using DongFangGuoKai.WMS.IApiService.ElectronicTags;
using DongFangGuoKai.WMSPlatform.Core;
using DongFangGuoKai.WMSPlatform.Domain.AGVModels;
using DongFangGuoKai.WMSPlatform.Domain.Enums;
using DongFangGuoKai.WMSPlatform.Domain.HZJLYModel;
using DongFangGuoKai.WMSPlatform.Domain.Models;
using DongFangGuoKai.WMSPlatform.Service.InboundOrderDetail.DTO;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Transactions;

namespace DongFangGuoKai.WMSPlatform.Service.InboundOrderDetail
{
    public partial class TReceivingOrderDetailService : ITReceivingOrderDetailService
    {
        #region 注入
        private readonly Repository<t_ReceivingBill> receivingbillrepost;
      
        private readonly IAGVService aGVService;
        private readonly IElectronicTSpreadWallsagsService electronicTSpreadWallsags;
        private readonly ILIMSService limsService;
        private readonly Repository<t_ReceivingBillDetail> receivingbillDteailrepost;
        private readonly Repository<t_Pallet> palletrepost;
        private readonly Repository<SpreadWalls> spreadwallsrepost;
        private readonly Repository<FullBoxRecords> fullboxrecordrepsot;
        private readonly Repository<t_Cell> cellrepost;
        private readonly Repository<t_StackingStorage> tStackingStorageServicerepost;
        private readonly Repository<UserColors> usercolorrepost;
        private readonly Repository<t_ReceivingOrderDetail> receivingOrderDetailrepost;
        private readonly Repository<t_Instruct> instructrepost;
        private readonly Repository<t_PutawayOrder> putawayorderrepost;
        private readonly Repository<t_Inventory> inventoryrepost;
        private readonly Repository<t_InventoryDetail> inventorydetailrepost;
        private readonly Repository<t_PutawayOrderDetail> putawayorderdetailrepost;
        private readonly Repository<t_InventoryLog> inventorylogrepost;



        public TReceivingOrderDetailService(
            Repository<t_ReceivingBill> receivingbillrepost,
            IAGVService aGVService,
            IElectronicTSpreadWallsagsService electronicTSpreadWallsags,
            ILIMSService limsService
            )
        {
            this.receivingbillrepost = receivingbillrepost;
            
            this.aGVService = aGVService;
            this.electronicTSpreadWallsags = electronicTSpreadWallsags;
            this.limsService = limsService;

            receivingbillDteailrepost =  receivingbillrepost.ChangeRepository<Repository<t_ReceivingBillDetail>>();
            palletrepost = receivingbillrepost.ChangeRepository<Repository<t_Pallet>>();
            spreadwallsrepost = receivingbillrepost.ChangeRepository<Repository<SpreadWalls>>();
            fullboxrecordrepsot = receivingbillrepost.ChangeRepository<Repository<FullBoxRecords>>();
            cellrepost = receivingbillrepost.ChangeRepository<Repository<t_Cell>>();
            tStackingStorageServicerepost = receivingbillrepost.ChangeRepository<Repository<t_StackingStorage>>();
            usercolorrepost = receivingbillrepost.ChangeRepository<Repository<UserColors>>();
            receivingOrderDetailrepost = receivingbillrepost.ChangeRepository<Repository<t_ReceivingOrderDetail>>();
            instructrepost = receivingbillrepost.ChangeRepository<Repository<t_Instruct>>();
            putawayorderrepost = receivingbillrepost.ChangeRepository<Repository<t_PutawayOrder>>();
            inventoryrepost = receivingbillrepost.ChangeRepository<Repository<t_Inventory>>();
            inventorydetailrepost = receivingbillrepost.ChangeRepository<Repository<t_InventoryDetail>>();
            putawayorderdetailrepost = receivingbillrepost.ChangeRepository<Repository<t_PutawayOrderDetail>>();
            inventorylogrepost = receivingbillrepost.ChangeRepository<Repository<t_InventoryLog>>();

        }
        #endregion




        /// <summary>
        /// 生成入库单或委托单单号
        /// </summary>
        /// <returns></returns>
        private string GetInOrderBarCode()
        {
            DateTime currentDateTime = DateTime.Now;
            string year = currentDateTime.ToString("yyyy");
            string month = currentDateTime.ToString("MM");
            string day = currentDateTime.ToString("dd");
            string hour = currentDateTime.ToString("HH");
            string minute = currentDateTime.ToString("mm");
            string second = currentDateTime.ToString("ss");
            Random random = new Random();
            string randomNumber = random.Next(1000000, 9999999).ToString();

            return $"{year}{month}{day}{hour}{minute}{second}{randomNumber}";
        }

        /// <summary>
        /// 添加入库委托单
        /// </summary>
        /// <param name="addReceivingBilDTO"></param>
        /// <param name="Message"></param>
        /// <returns></returns>
        public bool AddOrders(AddReceivingBilDTO addReceivingBilDTO, out string Message)
        {
            Message = "";
            lock (_lockObj)
            {
                try
                {
                    receivingbillrepost.AsTenant().BeginTran();
                    var rece = receivingbillrepost.GetFirst(r => r.BillNO == addReceivingBilDTO.OrderNo);
                    if (rece != null)
                    {
                        receivingbillrepost.AsTenant().RollbackTran();
                        Message = "用相同的验收单号";
                        return false;
                    }
                    if (addReceivingBilDTO.SampleInfo is null || addReceivingBilDTO.SampleInfo.Count <= 0)
                    {
                        receivingbillrepost.AsTenant().RollbackTran();
                        Message = "SampleInfo集合为空";
                        return false;
                    }
                    t_ReceivingBill receivingBill = new t_ReceivingBill();
                    receivingBill.CreateDate = DateTime.Now;
                    receivingBill.BillNO = addReceivingBilDTO.OrderNo;
                    receivingBill.Status = 0;
                    receivingBill.SampleTotalCount = addReceivingBilDTO.SampleTotalCount;
                    receivingBill.CustomerName = addReceivingBilDTO.CustomerName;
                    receivingBill.CustomerPhone = addReceivingBilDTO.CustomerPhone;
                    receivingBill.TotalQTY = addReceivingBilDTO.SampleInfo.Sum(r => r.SampleNum);
                    if (receivingbillrepost.Insert(receivingBill) == false)
                    {
                        receivingbillrepost.AsTenant().RollbackTran();
                        Message = "添加入库委托单失败";
                        return false;
                    }
                    List<t_ReceivingBillDetail> receivingBillDetails = new List<t_ReceivingBillDetail>();
                    foreach (var item in addReceivingBilDTO.SampleInfo)
                    {
                        if (item.PositionType is null)
                        {
                            Message = "存储位置为空";
                            receivingbillrepost.AsTenant().RollbackTran();
                            return false;
                        }
                        t_ReceivingBillDetail receivingBillDetail = new t_ReceivingBillDetail();
                        receivingBillDetail.BillNO = addReceivingBilDTO.OrderNo;
                        receivingBillDetail.BillId = receivingBill.Id;
                        receivingBillDetail.MaterialId = item.SampleId;
                        receivingBillDetail.MaterialCode = item.SampleCode;
                        receivingBillDetail.MaterialName = item.SamplelName;
                        receivingBillDetail.QTY = item.SampleNum.GetValueOrDefault();
                        receivingBillDetail.SampleSize = item.SampleSize;
                        receivingBillDetail.SampleTypeCode = item.SampleTypeCode;
                        receivingBillDetail.SampleWeight = item.SampleWeight;
                        receivingBillDetail.Laboratory = item.Laboratory;
                        receivingBillDetail.PositionType = item.PositionType;
                        receivingBillDetail.ReceivedQTY = 0;
                        receivingBillDetails.Add(receivingBillDetail);
                    }
                    if (receivingbillDteailrepost.InsertRange(receivingBillDetails))
                    {
                        receivingbillrepost.AsTenant().RollbackTran();
                        Message = "添加入库委托单明细失败";
                        return false;
                    }
                    receivingbillrepost.AsTenant().CommitTran();
                    return true;
                }
                catch (Exception ex)
                {
                    receivingbillrepost.AsTenant().RollbackTran();
                    Message = "添加入库委托单失败：" + ex.Message;
                    return false;
                    throw;
                }
            }
        }

        /// <summary>
        /// 作废委托单
        /// </summary>
        /// <param name="OrderNo"></param>
        /// <param name="errorMsg"></param>
        /// <returns></returns>
        public bool VoidOrder(string OrderNo, out string errorMsg)
        {
            errorMsg = string.Empty;
            try
            {
                receivingbillrepost.AsTenant().BeginTran();
                var receivingbill = receivingbillrepost.GetFirst(r => r.BillNO == OrderNo);
                if (receivingbill == null)
                {
                    errorMsg = "未查询到委托单";
                    return false;
                }
                receivingbill.Status = 3;
                if (!receivingbillrepost.Update(receivingbill))
                {
                    errorMsg = "委托单修改失败";
                    receivingbillrepost.AsTenant().RollbackTran();
                    return false;
                }
                var receivingbilldteail = receivingbillDteailrepost.GetList(r=>r.BillNO == receivingbill.BillNO);
                if (receivingbilldteail is null || receivingbilldteail.Count() <= 0)
                {
                    errorMsg = "委托单明细查询失败";
                    receivingbillrepost.AsTenant().RollbackTran();
                    return false;
                }
                foreach (var item in receivingbilldteail)
                {
                    item.Status = 4;
                    if (!receivingbillDteailrepost.Update(item))
                    {
                        errorMsg = "修改委托单明细失败";
                        receivingbillrepost.AsTenant().RollbackTran();
                        return false;
                    }
                }
                errorMsg = "提交成功";
                receivingbillrepost.AsTenant().CommitTran();
                return true;
            }
            catch (Exception ex)
            {
                errorMsg = "作废委托单失败：" + ex.Message;
                receivingbillrepost.AsTenant().RollbackTran();
                return false;
            }
        }

        /// <summary>
        /// 样品分实验室
        /// </summary>
        /// <param name="SampleId"></param>
        /// <param name="showColor"></param>
        /// <param name="errorMsg"></param>
        /// <returns></returns>
        public bool SortingLaboratory(string sampleCode, int showColor ,out string errorMsg)
        {
            errorMsg = string.Empty;
            try
            {
                receivingbillrepost.AsTenant().BeginTran();
                var receivingbilldetail = receivingbillDteailrepost.GetFirst(r => r.MaterialCode == sampleCode);
                if (receivingbilldetail == null)
                {
                    errorMsg = "未查询到此样品";
                    receivingbillrepost.AsTenant().RollbackTran();
                    return false;
                }
                var spreadlist = spreadwallsrepost.GetList(s => s.SeqNum == "1261703639" && s.Group == receivingbilldetail.Laboratory && s.SwitchState == 0);
                if (spreadlist is null || spreadlist.Count() <= 0)
                {
                    errorMsg = "没有标签地址，等等再试";
                    receivingbillrepost.AsTenant().RollbackTran();
                    return false;
                }
                bool result = false;
                foreach (var spread in spreadlist)
                {
                    //会有多个电子标签是指向一个实验室的所有要看那个地址现在具备往上放物料的条件
                    var pall = palletrepost.GetFirst(p => p.LocationCode == spread.CellCode && p.Status == 1);
                    if (pall is null)
                    {
                        result = false;
                        continue;
                    }
                    SuccessTagRequest successTagRequest = new SuccessTagRequest();
                    successTagRequest.nWall = spread.NWall;
                    successTagRequest.seqNum = spread.SeqNum;
                    successTagRequest.tagList = new List<Tag>()
                    {
                        new Tag()
                        {
                            showColor = showColor,
                            showData = "1",
                            tagIndex = spread.TagIndex,
                        }

                    };
                    var res = electronicTSpreadWallsags.successTagResults(successTagRequest, spreadwallsrepost, out errorMsg);
                    if (res)
                    {
                        var fullboxlist = fullboxrecordrepsot.GetFirst(f => f.Status == 0 && f.PalletBarcode == pall.PalletBarcode && f.MaterialId == receivingbilldetail.MaterialId);
                        if (fullboxlist == null)
                        {
                            FullBoxRecords fullBox = new FullBoxRecords()
                            {
                                CreateDate = DateTime.Now,
                                MaterialId = receivingbilldetail.MaterialId,
                                //MaterialCode = receivingbilldetail.MaterialCode,
                                MaterialName = receivingbilldetail.MaterialName,
                                OrderNo = receivingbilldetail.BillNO,
                                PalletBarcode = pall.PalletBarcode,
                                Status = 0
                            };

                            if (fullboxrecordrepsot.Insert(fullBox) == false)
                            {
                                errorMsg = "点亮失败，记录样品信息失败," + receivingbilldetail.MaterialName;
                                receivingbillrepost.AsTenant().RollbackTran();
                                return false;
                            }
                        }
                        receivingbillrepost.AsTenant().CommitTran();
                        errorMsg = "点亮成功,地址为：" + spread.TagIndex;
                        return true;
                    }
                    else
                    {
                        errorMsg = "点亮失败" + errorMsg;
                        receivingbillrepost.AsTenant().RollbackTran();
                        return false;
                    }
                }
                errorMsg = "没有标签地址，等等再试";
                receivingbillrepost.AsTenant().RollbackTran();
                return result;
            }
            catch (Exception ex)
            {
                errorMsg = "点亮失败：" + ex.Message;
                receivingbillrepost.AsTenant().RollbackTran();
                return false;
                throw;
            }
        }


        /// <summary>
        /// 样品分实验室满箱
        /// </summary>
        /// <param name="palletCode"></param>
        /// <returns></returns>
        public bool SortingLaboratoryFull(string palletCode, out string errorMsg)
        {
            errorMsg = string.Empty;
            try
            {
                receivingbillrepost.AsTenant().BeginTran();
                var pall = palletrepost.GetFirst(p=>p.PalletBarcode == palletCode);
                if (pall == null || pall.LocationCode == null)
                {
                    errorMsg = "未查询到箱子";
                    receivingbillrepost.AsTenant().RollbackTran();
                    return false;
                }

                var fullboxs = fullboxrecordrepsot.GetList(f=> f.PalletBarcode == pall.PalletBarcode && f.Status == 0);
                if (fullboxs is null || fullboxs.Count() <= 0)
                {
                    errorMsg = "箱子还没有分拣样品";
                    receivingbillrepost.AsTenant().RollbackTran();
                    return false;
                }

                foreach (var fullbox in fullboxs)
                {
                    fullbox.Status = 1;
                    if (!fullboxrecordrepsot.Update(fullbox))
                    {
                        errorMsg = "分拣样品信息修改失败";
                        receivingbillrepost.AsTenant().RollbackTran();
                        return false;
                    }
                }

                var cell = cellrepost.GetFirst(c => c.Code == pall.LocationCode);
                if (cell is null)
                {
                    errorMsg = "箱子所在储位未找到";
                    receivingbillrepost.AsTenant().RollbackTran();
                    return false;
                }
                var spobj = spreadwallsrepost.GetFirst(s => s.CellCode == cell.Code);
                if (spobj == null)
                {
                    errorMsg = "储位不在分播墙上";
                    receivingbillrepost.AsTenant().RollbackTran();
                    return false;
                }

                pall.LocationCode = null;
                pall.LocationName = null;
                pall.ERPLocationName = null;
                if (!palletrepost.Update(pall))
                {
                    errorMsg = "修改箱子数据失败";
                    receivingbillrepost.AsTenant().RollbackTran();
                    return false;
                }

                /*

                //TInstruct instruct = new TInstruct()
                //{
                //    Status = 2,
                //    ToLocation = "",

                //    WorkDeviceType = EmWorkDeviceType.AGV,
                //    InstructType = EmInstructType.In,//补空箱
                //    Action = EmDeviceAction.Transport,
                //    //RelatedOrderDetailId = orderDetail.Id,//换成code
                //    //RelatedOrderDetailCode = orderDetail.OrderSn,
                //    DeviceCode = "",
                //    ExpectedToLocation ="", //需要换成箱子的所在位置
                //    InstructIndex = 1,
                //    PalletBarcode = pall.PalletBarcode,
                //    ScanedBarcode = pall.PalletBarcode,
                //    Priority = 9999,
                //    //Qty = materialNum.GetValueOrDefault(),
                //    FinishedQty = 0,
                //    LogicalCellAddr = cell.Erpcode,
                //    StartTime = DateTime.Now,
                //    BusinessGroupId = Guid.NewGuid(),
                //    BusinessType = (int)EmBusinessType.None,
                //    //BillType = (int)orderDetail.BillType.GetValueOrDefault(),
                //};

                //调用avg补空箱
                //var result =  SupplementNullBox(instruct,"2",out errorMsg);
                //if (result)
                //{
                //    errorMsg = "avg返回结果：" + errorMsg;
                //    trans.Dispose();
                //    return false;
                //}
                */

                errorMsg = "成功";
                receivingbillrepost.AsTenant().CommitTran();
                return true;
            }
            catch (Exception ex)
            {
                errorMsg = "失败：" + ex.Message;
                receivingbillrepost.AsTenant().RollbackTran();
                return false;
                throw;
            }

        }

    }
}
